Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.

...powered by www.netzwerkartist.de...

 << zurück
Visual C# 2005 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2005

Visual C# 2005
1.320 S., mit 2 CDs, 59,90 Euro
Galileo Computing
ISBN 3-89842-586-X
gp Kapitel 6 Vererbung, Polymorphie und Schnittstellen
  gp 6.1 Basisklassen und abgeleitete Klassen
    gp 6.1.1 Ableiten einer Klasse
    gp 6.1.2 Klassen, die nicht vererben können
    gp 6.1.3 Zusammenfassung
  gp 6.2 Konstruktoren in abgeleiteten Klassen
    gp 6.2.1 Die Konstruktoren der Klasse »GraphicCircle«
    gp 6.2.2 Der Zugriffsmodifizierer »protected«
    gp 6.2.3 Konstruktorverkettung
    gp 6.2.4 Destruktor-Verkettung
    gp 6.2.5 Der Stand des Projekts »CircleApplication«
    gp 6.2.6 Zusammenfassung
  gp 6.3 Die Methoden in einer abgeleiteten Klasse
    gp 6.3.1 Geerbte Methoden mit »new« verdecken
    gp 6.3.2 Überladen einer Basisklassenmethode
  gp 6.4 Ereignisse in der Vererbung
  gp 6.5 »Hat-eine«-Beziehungen (Aggregation)
    gp 6.5.1 Weiterleitung einer internen Objektreferenz
    gp 6.5.2 Verbergen des internen Objekts
    gp 6.5.3 Innere Klassen
  gp 6.6 Typumwandlung von Objektvariablen
    gp 6.6.1 Die implizite Typumwandlung von Objektreferenzen
    gp 6.6.2 Die explizite Typumwandlung von Objektreferenzen
    gp 6.6.3 Zusammenfassung
  gp 6.7 Abstrakte Klassen und Methoden
    gp 6.7.1 Abstrakte Definitionen
  gp 6.8 Polymorphie
    gp 6.8.1 Virtuelle Methoden
    gp 6.8.2 Inhomogene Mengen
    gp 6.8.3 Verdecken und Überschreiben geerbter Methoden
    gp 6.8.4 Überschreiben der Methode »ToString()« der Klasse »Object«
    gp 6.8.5 Versiegelte Methoden
    gp 6.8.6 Zusammenfassung
  gp 6.9 Erweiterung der Klassenhierarchie »CircleApplication«
    gp 6.9.1 Die Klasse »GeometricObject«
  gp 6.10 Schnittstellen
    gp 6.10.1 Einführung in die Schnittstellen
    gp 6.10.2 Schnittstellendefinition
    gp 6.10.3 Schnittstellenimplementierung
    gp 6.10.4 Typumwandlung mit dem »as«-Operator
    gp 6.10.5 Abstrakte Klassen vs. Schnittstellen
    gp 6.10.6 Zusammenfassung


Galileo Computing

6.7 Abstrakte Klassen und Methoden  downtop

Je weiter man nach »oben« in einer Klassenhierarchie geht, desto allgemeiner und unverbindlicher werden die Klassen. Die oberste Klasse ist meistens so allgemein, dass man sie sich gerade noch als Gerüst oder als Oberbegriff für alle abgeleiteten Klassen vorstellen kann. Denken Sie noch einmal an das Beispiel der Klassenhierarchie der Luftfahrzeuge. Ein Programm, das diese Hierarchie nutzt, wird Instanzen der Klassen Hubschrauber, Zeppelin und Starrflügler erstellen. Den aus diesen drei Klassen erstellten Objekten sind einige Verhaltensweisen und Eigenschaften gemein: Alle Objekte werden – unabhängig vom Typ – sowohl starten als auch fliegen und landen können, alle werden einen Kaufpreis haben, einen Hersteller usw.

Haben Sie dieses Kapitel von Anfang an aufmerksam gelesen, werden Sie die Schlussfolgerung ziehen, dass man die gemeinsamen Entitäten der verschiedenen Objekte sinnvollerweise in der Basisklasse Luftfahrzeug implementiert und an die Subklassen vererbt.

Vom Ansatz her ist diese Idee richtig, aber denken Sie einen Schritt weiter: Wie soll beispielsweise die Methode Starten in Luftfahrzeug implementiert werden? Ein Starrflügler wird anders starten als ein Hubschrauber und ein Hubschrauber wiederum anders als ein Zeppelin. Ein Flugzeug benötigt eine Startbahn mit einer Mindestlänge, um überhaupt abheben zu können, während für einen Hubschrauber bereits eine freie Fläche in einer Größe genügt, die gewährleistet, dass die Rotorspitzen keine Hindernisse streifen. Um einen Zeppelin zu starten, wird eine Mannschaft benötigt, die das Halteseil löst und das Luftschiff zum Starten freigibt.

Ein neues Problem wird plötzlich offensichtlich: Wie kann das Startverhalten in der Basisklasse implementiert werden, wenn es für die Objekte der abgeleiteten Typen Zeppelin, Hubschrauber und Starrflügler unterschiedlich beschrieben werden muss? Ein trivialer Lösungsansatz würde die Methode Starten in der Basisklasse definieren und den Startvorgang eines beliebigen Typs implementieren – zum Beispiel den eines Starrflüglers. Zugegeben, für die meisten real existierenden Flugobjekte würde damit die passende Implementierung geliefert. Die anderen beiden Typen würden diese Methode zwar erben, müssten aber darauf achten, sie mit new zu verdecken und neu zu implementieren.

Das kann es aber doch nicht sein, was wir wirklich wollen: Eine bestimmte Subklasse erbt die Funktionalität ihrer Basisklasse und kann sie uneingeschränkt nutzen, alle anderen Subklassen stehen in der Verantwortung, die geerbte Methode durch eine individuelle Implementierung zu ersetzen. Wird das in der Zeppelin-Klasse versäumt, rast ein Zeppelin beim Starten über die 2.000 m lange Startbahn bis zur Abhebegeschwindigkeit von 250 km/h ... sicherlich sehr zum Leidwesen der Bodenmannschaft.


Galileo Computing

6.7.1 Abstrakte Definitionen  toptop

Der Lösung haftet anscheinend der Nachteil an, dass sie in den abgeleiteten Klassen nicht auf die gleiche Weise behandelt werden kann. Sie ist damit fehlerträchtig und nicht gut. Jede abgeleitete Klasse sollte hinsichtlich der Behandlung einer Basisklassenoperation gleichwertig sein: Entweder müssen alle abgeleiteten Klassen die Starten-Methode neu implementieren oder keine. Nur so lassen sich potenzielle Fehler im Ansatz vermeiden.

Die Lösung der erkannten Problematik mag im ersten Moment verblüffen: Tatsächlich wird die Methode Starten in der Basisklasse nicht implementiert – sie bleibt einfach ohne Programmcode. In der objektorientierten Programmierung werden solche Methoden, die keinen Code enthalten, als abstrakte Methoden bezeichnet. Neben den das Verhalten eines Typs beschreibenden Methoden können auch Eigenschaften abstrakt definiert werden.

In C# werden abstrakte Methoden durch die Angabe des abstract-Modifizierers in der Methodensignatur gekennzeichnet, am Beispiel unserer Starten-Methode also:


public abstract void Starten();

Abstrakte Methoden enthalten grundsätzlich keinen Code. Daher wird die Definition einer abstrakten Methode mit einem Semikolon hinter der Parameterliste abgeschlossen, die geschweiften Klammern des Anweisungsblocks entfallen.

Welchen Stellenwert nimmt aber eine Klasse ein, die eine Methode veröffentlicht, die keinerlei Verhalten aufweist? Die Antwort ist verblüffend, eine solche Klasse kann nicht instanziiert werden – sie rechtfertigt ihre Existenz einzig und allein dadurch, als Methodengeber für abgeleitete Klassen zu dienen. Damit wird das Prinzip der objektorientierten Programmierung, gemeinsame Verhaltensweisen auf eine höhere Ebene auszulagern, nahezu auf die Spitze getrieben.

Eine nicht instanziierbare Klasse, die mindestens ein durch abstract gekennzeichnetes Member enthält, ist ihrerseits selbst abstrakt und wird deshalb als abstrakte Klasse bezeichnet. Abstrakte Klassen machen nur dann Sinn, wenn sie abgeleitet werden. Syntaktisch wird dieses Verhalten in C# durch die Ergänzung des Modifikators abstract in der Klassensignatur beschrieben:


public abstract class Luftfahrzeug {
  public abstract void Starten();
  ...
}

Neben abstrakten Methoden darf eine abstrakte Klasse auch vollständig implementierte Methoden und Eigenschaften bereitstellen. So könnte die Klasse Luftfahrzeug beispielsweise den Hersteller des Luftfahrzeugs über eine Eigenschaftsmethode speichern und zurückgeben:


public abstract class Luftfahrzeug {
  private string hersteller;
  // abstrakte Methode
  public abstract void Starten();
  // konkrete Eigenschaft
  public string Hersteller    {
    get {return hersteller;} 
    set {hersteller = value;}
  }
}

Die Signierung einer Methode und infolgedessen auch der dazugehörigen Klasse mit dem Modifizierer abstract kommt einer Forderung gleich:


Alle nicht abstrakten Ableitungen einer abstrakten Klasse müssen die abstrakten Methoden der Basisklasse überschreiben.

Wird in einer abgeleiteten Klasse das abstrakte Mitglied der Basisklasse nicht überschrieben, muss die Subklasse in jedem Fall ebenfalls abstract gekennzeichnet werden. Als Konsequenz dieser Aussagen bilden abstrakte Klassen das Gegenkonstrukt zu den Klassen, die mit sealed als nicht ableitbar gekennzeichnet sind. Daraus folgt auch, dass die Modifizierer sealed und abstract nicht nebeneinander verwendet werden dürfen.

Das folgende Codefragment beschreibt die Klasse Hubschrauber. In der Klassenimplementierung wird die abstrakte Methode Starten der Basisklasse überschrieben. Zur Kennzeichnung des Überschreibens einer abstrakten Basisklassenmethode dient der Modifizierer override in der überschreibenden Methode:


class Hubschrauber : Luftfahrzeug {
  public override void Starten() { 
    Console.WriteLine("Der Hubschrauber startet");
  }
}

Eine Klasse, die eine abstrakt definierte Methode enthält, muss ihrerseits selbst abstrakt sein. Der Umkehrschluss ist allerdings nicht richtig, denn eine abstrakte Klasse ist nicht zwangsläufig dadurch gekennzeichnet, ein abstraktes Mitglied zu enthalten. Eine Klasse kann auch dann abstrakt sein, wenn keiner ihrer Member abstrakt ist. Auf diese Weise wird eine Klasse nicht instanziierbar und das Ableiten dieser Klasse erzwungen.


abstract kann nur im Zusammenhang mit Instanzmembern benutzt werden. Statische Methoden können nicht abstrakt definiert werden, deshalb ist das gleichzeitige Auftreten von static und abstract in einer Methodensignatur nicht zulässig.

 << zurück
  
  Zum Katalog
Zum Katalog: Visual C# 2005
Visual C# 2005
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Fortgeschrittene Programmierung mit Visual C# 2005






 Fortgeschrittene
 Programmierung
 mit Visual C# 2005


Zum Katalog: Einstieg in Visual C# 2005






 Einstieg in
 Visual C# 2005


Zum Katalog: Einstieg in Visual Basic 2005






 Einstieg in
 Visual Basic 2005


Zum Katalog: Visual Basic 2005






 Visual Basic 2005


Zum Katalog: Java ist auch eine Insel






 Java ist auch eine
 Insel


Zum Katalog: Konzepte und Lösungen für Microsoft-Netzwerke






 Konzepte und
 Lösungen für
 Microsoft-Netzwerke


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo








Copyright © Galileo Press 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de